package com.nuaa.likesystem.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuaa.likesystem.common.ErrorCode;
import com.nuaa.likesystem.constant.ThumbConstant;
import com.nuaa.likesystem.domain.ThumbDomain;
import com.nuaa.likesystem.exception.BusinessException;
import com.nuaa.likesystem.mapper.ThumbMapper;
import com.nuaa.likesystem.model.dto.thumb.DoThumbRequest;
import com.nuaa.likesystem.model.entity.Blog;
import com.nuaa.likesystem.model.entity.Thumb;
import com.nuaa.likesystem.model.entity.User;
import com.nuaa.likesystem.service.BlogService;
import com.nuaa.likesystem.service.ThumbService;
import com.nuaa.likesystem.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.concurrent.TimeUnit;

/**
 * @author 11352
 * @description 针对表【thumb】的数据库操作Service实现
 * @createDate 2025-04-20 17:51:56
 */
@Service
public class ThumbServiceImpl extends ServiceImpl<ThumbMapper, Thumb> implements ThumbService {

	@Resource
	private BlogService blogService;

	@Resource
	private UserService userService;

	@Resource
	private TransactionTemplate transactionTemplate;

	@Resource
	private RedisTemplate<String, Object> redisTemplate;

	@Resource
	private ThumbDomain thumbDomain;

	@Override
	public Boolean doThumb(DoThumbRequest doThumbRequest, HttpServletRequest request) {
		if (doThumbRequest == null || doThumbRequest.getBlogId() == null) {
			throw new BusinessException(ErrorCode.SYSTEM_ERROR, "参数错误");
		}
		User loginUser = userService.getLoginUser(request);
		// 加锁
		synchronized (loginUser.getId()
		                       .toString()
		                       .intern()) {

			// 编程式事务
			return transactionTemplate.execute(status -> {
				Long blogId = doThumbRequest.getBlogId();
				//boolean exists = this.lambdaQuery()
				//                     .eq(Thumb::getUserId, loginUser.getId())
				//                     .eq(Thumb::getBlogId, blogId)
				//                     .exists();
				Boolean exists = thumbDomain.hasThumb(blogId, loginUser.getId());
				if (exists) {
					throw new BusinessException(ErrorCode.SYSTEM_ERROR, "用户已点赞");
				}

				boolean update = blogService.lambdaUpdate()
				                            .eq(Blog::getId, blogId)
				                            .setSql("thumbCount = thumbCount + 1")
				                            .update();

				Thumb thumb = new Thumb();
				thumb.setUserId(loginUser.getId());
				thumb.setBlogId(blogId);
				// 更新成功才执行
				boolean success = update && this.save(thumb);

				// 点赞记录存入 Redis
				if (success) {
					String hashKey = ThumbConstant.USER_THUMB_KEY_PREFIX + loginUser.getId()
					                                                                .toString();
					redisTemplate.opsForHash()
					             .put(hashKey, blogId.toString(), thumb.getId());
					// 设置过期时间为30天（单位：秒）
					redisTemplate.expire(hashKey, 30 * 24 * 60 * 60, TimeUnit.SECONDS);
				}

				// 更新成功才执行
				return success;

			});
		}
	}

	@Override
	public Boolean undoThumb(DoThumbRequest doThumbRequest, HttpServletRequest request) {
		if (doThumbRequest == null || doThumbRequest.getBlogId() == null) {
			throw new BusinessException("参数错误");
		}
		User loginUser = userService.getLoginUser(request);
		// 加锁
		synchronized (loginUser.getId()
		                       .toString()
		                       .intern()) {

			// 编程式事务
			return transactionTemplate.execute(status -> {
				Long blogId = doThumbRequest.getBlogId();
				//Thumb thumb = this.lambdaQuery()
				//                  .eq(Thumb::getUserId, loginUser.getId())
				//                  .eq(Thumb::getBlogId, blogId)
				//                  .one();
				//if (thumb == null) {
				//	throw new BusinessException("用户未点赞");
				//}
				Object thumbIdObj = redisTemplate.opsForHash()
				                                 .get(ThumbConstant.USER_THUMB_KEY_PREFIX + loginUser.getId()
				                                                                                     .toString(), blogId.toString());
				if (thumbIdObj == null) {
					throw new RuntimeException("用户未点赞");
				}
				Long thumbId = Long.valueOf(thumbIdObj.toString());

				boolean update = blogService.lambdaUpdate()
				                            .eq(Blog::getId, blogId)
				                            .setSql("thumbCount = thumbCount - 1")
				                            .update();

				boolean success = update && this.removeById(thumbId);

				// 点赞记录从 Redis 删除
				if (success) {
					redisTemplate.opsForHash()
					             .delete(ThumbConstant.USER_THUMB_KEY_PREFIX + loginUser.getId(), blogId.toString());
				}
				return success;

			});
		}
	}
}




